package cn.edu.sdjzu.knoverse.config;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpUtil;
import cn.edu.sdjzu.knoverse.constant.SaSessionConstant;
import cn.edu.sdjzu.knoverse.model.entity.system.Power;
import cn.edu.sdjzu.knoverse.model.entity.system.Role;
import cn.edu.sdjzu.knoverse.mapper.PowerMapper;
import cn.edu.sdjzu.knoverse.mapper.RoleMapper;
import cn.edu.sdjzu.knoverse.model.vo.system.user.LoginVo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义权限加载接口实现类
 */
@Component    // 保证此类被 SpringBoot 扫描，完成 Sa-Token 的自定义权限验证扩展
public class StpInterfaceImpl implements StpInterface {
    @Resource
    private RoleMapper roleMapper;

    @Resource
    private PowerMapper powerMapper;

    /**
     * 返回一个账号所拥有的权限码集合
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 优先从 Session 中获取权限列表
        SaSession session = StpUtil.getSession();
        LoginVo loginVo = session.get(SaSessionConstant.USER, null);
        
        if (loginVo != null && loginVo.getPermissions() != null && !loginVo.getPermissions().isEmpty()) {
            return loginVo.getPermissions();
        }
        
        // 如果 Session 中没有，则从数据库查询
        List<Power> list = powerMapper.selectListByUserId(Long.parseLong((String) StpUtil.getLoginId()));
        List<String> permissionList = new ArrayList<>();
        for (Power power : list) {
            permissionList.add(power.getPowerCode());
        }
        
        // 将查询结果更新到 Session 中
        if (loginVo != null) {
            loginVo.setPermissions(permissionList);
            session.set(SaSessionConstant.USER, loginVo);
        }
        
        return permissionList;
    }

    /**
     * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        // 优先从 Session 中获取角色列表
        SaSession session = StpUtil.getSession();
        LoginVo loginVo = session.get(SaSessionConstant.USER, null);
        
        if (loginVo != null && loginVo.getRoles() != null && !loginVo.getRoles().isEmpty()) {
            return loginVo.getRoles();
        }
        
        // 如果 Session 中没有，则从数据库查询
        long userId = Long.parseLong(loginId.toString());
        List<Role> roleList = roleMapper.selectListByUserId(userId);
        List<String> roles = roleList.stream().map(Role::getRoleCode).toList();
        
        // 将查询结果更新到 Session 中
        if (loginVo != null) {
            loginVo.setRoles(roles);
            session.set(SaSessionConstant.USER, loginVo);
        }
        
        return roles;
    }
}
